package com.onesports.intelligent.k12.polarlight.service.organization;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.onesports.framework.kit.common.util.BeanUtils;
import com.onesports.framework.kit.common.util.ParamUtils;
import com.onesports.intelligent.k12.polarlight.common.domain.entity.BaseEntity;
import com.onesports.intelligent.k12.polarlight.common.errors.exceptions.BusinessException;
import com.onesports.intelligent.k12.polarlight.common.utils.Assert;
import com.onesports.intelligent.k12.polarlight.domain.dto.organization.OrganizationStaffDTO;
import com.onesports.intelligent.k12.polarlight.domain.dto.organization.OrganizationStaffQueryDTO;
import com.onesports.intelligent.k12.polarlight.domain.dto.sys.RunAccountDTO;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.CampusStaffRel;
import com.onesports.intelligent.k12.polarlight.domain.entity.organization.OrganizationStaff;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.Account;
import com.onesports.intelligent.k12.polarlight.domain.entity.sys.Role;
import com.onesports.intelligent.k12.polarlight.domain.vo.organization.OrganizationStaffVO;
import com.onesports.intelligent.k12.polarlight.enums.OrganizationStaffTypeEnum;
import com.onesports.intelligent.k12.polarlight.mapper.organization.CampusStaffRelMapper;
import com.onesports.intelligent.k12.polarlight.mapper.organization.OrganizationStaffMapper;
import com.onesports.intelligent.k12.polarlight.security.SecurityUtils;
import com.onesports.intelligent.k12.polarlight.service.coach.CoachManager;
import com.onesports.intelligent.k12.polarlight.service.sys.RoleService;
import com.onesports.intelligent.k12.polarlight.service.sys.RunAccountService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Wsy
 **/
@Service
@RequiredArgsConstructor
public class OrganizationStaffService extends ServiceImpl<OrganizationStaffMapper, OrganizationStaff> {
    private final RunAccountService runAccountService;
    private final CampusStaffRelMapper campusStaffRelMapper;
    private final RoleService roleService;
    
    private final CoachManager coachManager;

    /**
     * 分页查询
     *
     * @param dto
     * @return
     */
    public IPage<OrganizationStaffVO> page(OrganizationStaffQueryDTO dto) {
        dto.setOrganizationId(SecurityUtils.getOrganizationId());
        return baseMapper.page(new Page<>(dto.getPage(), dto.getRow()), dto);
    }

    /**
     * 添加员工
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public OrganizationStaff add(OrganizationStaffDTO dto, OrganizationStaffTypeEnum organizationStaffType) {
        OrganizationStaff useStaff = checkExist(dto);
        OrganizationStaff staff = BeanUtils.copyProperties(dto, OrganizationStaff.class);
        if (null != useStaff) {
            if (useStaff.getStaffType().equals(organizationStaffType.getValue()) || useStaff.getStaffType()
                    .equals(OrganizationStaffTypeEnum.STAFF_COACH.getValue())) {
                throw new BusinessException("员工已存在");
            }
            //已存在不同类型的员工数据，做修改操作
            dto.setId(useStaff.getId());
            dto.setStaffType(OrganizationStaffTypeEnum.STAFF_COACH.getValue());
            return edit(dto,false);
        }
        staff.setStaffType(organizationStaffType.getValue());
        RunAccountDTO accountDTO = BeanUtils.copyProperties(dto, RunAccountDTO.class);
        accountDTO.setStatus(true);
        accountDTO.setUsername(dto.getStaffName());
        Account account = runAccountService.add(accountDTO, dto.getOrganizationId());
        staff.setAccountId(account.getId());
        staff.setOrganizationId(account.getOrganizationId());
        baseMapper.insert(staff);
        if (CollectionUtils.isNotEmpty(dto.getCampusIds())) {
            dto.getCampusIds().forEach(campusId -> {
                CampusStaffRel campusStaffRel = new CampusStaffRel();
                campusStaffRel.setOrganizationId(staff.getOrganizationId());
                campusStaffRel.setStaffId(staff.getId());
                campusStaffRel.setCampusId(campusId);
                campusStaffRelMapper.insert(campusStaffRel);
            });
        }
        return staff;
    }

    /**
     * 修改
     *
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    public OrganizationStaff edit(OrganizationStaffDTO dto,boolean isSyncCoachCampus) {
        Assert.isTrue(StringUtils.isNotBlank(dto.getId()), "ID不能为空");
        OrganizationStaff useStaff = checkExist(dto);
        if (null != useStaff) {
            throw new BusinessException("员工已存在");
        }
        RunAccountDTO accountDTO = BeanUtils.copyProperties(dto, RunAccountDTO.class);
        OrganizationStaff staff = BeanUtils.copyProperties(dto, OrganizationStaff.class);
        OrganizationStaff staffEn = baseMapper.selectById(dto.getId());
        baseMapper.updateById(staff);
        accountDTO.setId(staffEn.getAccountId());
        if(staffEn.getIsPrincipal()&&CollectionUtils.isNotEmpty(accountDTO.getRoleIds())){
            //负责人不修改角色
            Role superRole = roleService.getSuperRole(staffEn.getOrganizationId());
            accountDTO.getRoleIds().add(superRole.getId());
        }
        runAccountService.edit(accountDTO);
        if (CollectionUtils.isNotEmpty(dto.getCampusIds())) {
            campusStaffRelMapper.delete(new QueryWrapper<CampusStaffRel>().lambda().eq(CampusStaffRel::getStaffId, staff.getId()));
            dto.getCampusIds().forEach(campusId -> {
                CampusStaffRel campusStaffRel = new CampusStaffRel();
                campusStaffRel.setOrganizationId(staff.getOrganizationId());
                campusStaffRel.setStaffId(staff.getId());
                campusStaffRel.setCampusId(campusId);
                campusStaffRelMapper.insert(campusStaffRel);
            });
        }

        if(isSyncCoachCampus){
            //同步教练校区
            if(null==dto.getCampusIds()){
                dto.setCampusIds(Lists.newArrayList());
            }
            coachManager.syncCampus(dto.getId(),dto.getCampusIds(),dto.getOrganizationId());
        }
        return staff;
    }

    /**
     * 删除机构时删除员工
     * @param organizationId
     */
    @Transactional(rollbackFor = Exception.class)
    public void delByOrganizationId(String organizationId){
        List<OrganizationStaff> organizationStaffs = baseMapper.selectList(new LambdaQueryWrapper<OrganizationStaff>().eq(OrganizationStaff::getOrganizationId,organizationId));
        if(CollectionUtils.isNotEmpty(organizationStaffs)){
            organizationStaffs.forEach(staff->{
                runAccountService.delete(staff.getAccountId());
                removeById(staff);
            });
        }
    }

    /**
     * 添加超级管理员权限的机构负责人
     */
    public void addSuper(String staffName, String phone, String organizationId) {
        Role superRole = roleService.getSuperRole(organizationId);
        List<String> roleIds = Lists.newArrayList();
        roleIds.add(superRole.getId());
        OrganizationStaffDTO dto = new OrganizationStaffDTO();
        dto.setOrganizationId(organizationId);
        dto.setStaffName(staffName);
        dto.setPhone(phone);
        dto.setRoleIds(roleIds);
        dto.setIsPrincipal(true);
        add(dto, OrganizationStaffTypeEnum.STAFF);
    }

    public OrganizationStaffVO getOrganizationStaffByPhone(String phone, String organizationId) {
        List<OrganizationStaff> staffList = baseMapper.selectList(new QueryWrapper<OrganizationStaff>().lambda()
                .eq(BaseEntity::getDeleted, false)
                .eq(ParamUtils.isNotEmpty(organizationId), OrganizationStaff::getOrganizationId, organizationId)
                .eq(OrganizationStaff::getPhone, phone));
        if (staffList.size() > 0) {
            return BeanUtils.copyProperties(staffList.get(0), OrganizationStaffVO.class);
        }
        return null;
    }

    /**
     * 校验员工是否存在
     */
    public OrganizationStaff checkExist(OrganizationStaffDTO dto) {
        List<OrganizationStaff> staffList = baseMapper.selectList(new QueryWrapper<OrganizationStaff>().lambda()
                .ne(ParamUtils.isNotEmpty(dto.getId()), BaseEntity::getId, dto.getId())
                .eq(BaseEntity::getDeleted, false)
                .eq(OrganizationStaff::getPhone, dto.getPhone()));
        if (staffList.size() > 0) {
            OrganizationStaff staff = staffList.get(0);
            if (!staff.getOrganizationId().equals(dto.getOrganizationId())) {
                throw new BusinessException("员工已存在其他机构中");
            }
            return staff;
        }
        return null;
    }
}
